# -*- coding: utf-8 -*-
'''
Graphs.py: This module generates graphs with Matplotlib
'''

from WriteDatabaseSQLalchemy import Dados
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import matplotlib.pyplot as plt
import numpy as np


class Graphs():

    def __init__(self):

        engine = create_engine('sqlite:///database.db', echo=False)
        Session = sessionmaker(bind = engine)
        self.session = Session()
        # Label x pre definida
        self.xlabel = 'Anos'
        # Dicionário das labels (y)
        self.ylabels = {u'IPC Global': u'Índice',
                        u'Variação Anual (Taxa de Inflação)': u'Por cento (%)',
                        u'Remuneração miníma mensal': u'Euros (€)',
                        u'Remuneração máxima mensal': u'Euros (€)',
                        u'PIB per capita anual': u'Euros (€)',
                        u'Rendimento nacional bruto per capita anual': u'Euros (€)',
                        u'Rendimento disponível bruto per capita anual': u'Euros (€)',
                        u'Remunerações per capita anual': u'Euros (€)'}
        # Dicionário das cores (para usar no matplotlib)
        self.colors = {u'Azul': 'blue',
                       u'Verde': 'green',
                       u'Vermelho': 'red',
                       u'Amarelo': 'yellow',
                       u'Preto': 'black',
                       u'Branco': 'white'}

    def getYears(self, excludeYear = 0):
        '''
        This method returns a list with years excluding the excludeYear param
        '''
        years = []
        
        for row in self.session.query(Dados).all():
            if(excludeYear != int(row.ano)):
                years.append(row.ano)

        return years
    
    def getData(self, dataType, begin = 1977, end = 2013):
        '''
        This method returns a list of data to be used on graphs
        '''
        data = []
        
        for x in range(begin, end + 1):
            res = self.session.query(Dados).filter(Dados.ano == x).first()
            value = ""
            if dataType == u"IPC Global":
                value = res.ipc_global_1981_100
            elif dataType == u"Variação Anual (Taxa de Inflação)":
                value = res.variacao_anual_taxa_de_inflacao
            elif dataType == u"Remuneração miníma mensal":
                value = res.remuneracao_minima_mensal
            elif dataType == u"Remuneração máxima mensal":
                value = res.remuneracao_maxima_mensal
            elif dataType == u"PIB per capita anual":
                value = res.pib_per_capita_anual
            elif dataType == u"Rendimento nacional bruto per capita anual":
                value = res.rendimento_nacional_bruto_per_capita_anual
            elif dataType == u"Rendimento disponível bruto per capita anual":
                value = res.rendimento_disponivel_bruto_per_capita_anual
            elif dataType == u"Remunerações per capita anual":
                value = res.remuneracoes_per_capita_anual

            if value == '':
                data.append(0)
            else:
                data.append(float(value))

        return data

    def getMultipleData(self, dataTypeList, begin, end):
        '''
        This method returns a list of lists of data to be used on graphs
        '''
        dataList = []
        
        for item in dataTypeList:
            dataList.append(self.getData(item, begin, end))
            
        return dataList
        
    def createGraphBasicBarChart(self, dataType, begin, end, color):
        '''
        This method draws a bar chart
        '''
        data = self.getData(dataType, begin, end)
        yearRange = np.arange(begin, end + 1)
        f = plt.figure() #
        ax = f.add_subplot(111) #
        ax.bar(yearRange, data, color = self.colors[color])
    
        # text for labels
        ax.set_xlabel(self.xlabel)
        ax.set_ylabel(self.ylabels[dataType])
        ax.set_title(dataType)

        # valores minimos e maximos do array data
        maxValue = 0
        minValue = 0
        for i in data:
            if i > maxValue:
                maxValue = i
            elif i < minValue:
                minValue = i
    
        if minValue < 0:
            plt.axis([begin, end, minValue, maxValue])
        else:
            plt.axis([begin, end, 0, maxValue])
            
        plt.grid(True)
        return f
    
    def createGraphBasicLineChart(self, dataType, begin, end, color):
        '''
        This method draws a line chart
        '''
        data = self.getData(dataType, begin, end)
        yearRange = np.arange(begin, end + 1)
        f = plt.figure() #
        ax = f.add_subplot(111) #
        ax.plot(yearRange, data, color = self.colors[color], lw=2)

        # text for labels
        ax.set_xlabel(self.xlabel)
        ax.set_ylabel(self.ylabels[dataType])
        ax.set_title(dataType)

        # valores minimos e maximos do array data
        maxValue = 0
        minValue = 0
        for i in data:
            if i > maxValue:
                maxValue = i
            elif i < minValue:
                minValue = i
    
        if minValue < 0:
            plt.axis([begin, end, minValue, maxValue])
        else:
            plt.axis([begin, end, 0, maxValue])

        plt.grid(True)
        return f

    def createGraphScatterChart(self, dataType, begin, end, color):
        '''
        This method draws a scatter chart
        '''
        data = self.getData(dataType, begin, end)
        yearRange = np.arange(begin, end + 1)
        f = plt.figure() #
        ax = f.add_subplot(111) #
        ax.scatter(yearRange, data, color = self.colors[color])
    
        # text for labels
        ax.set_xlabel(self.xlabel)
        ax.set_ylabel(self.ylabels[dataType])
        ax.set_title(dataType)

        # valores minimos e maximos do array data
        maxValue = 0
        minValue = 0
        for i in data:
            if i > maxValue:
                maxValue = i
            elif i < minValue:
                minValue = i
    
        if minValue < 0:
            plt.axis([begin, end, minValue, maxValue])
        else:
            plt.axis([begin, end, 0, maxValue])
    
        plt.grid(True)
        return f

    def createGraphMultipleLineChart(self, dataTypeList, begin, end):
        '''
        This method draws a multiple line chart
        '''
        data = self.getMultipleData(dataTypeList, begin, end)
        yearRange = np.arange(begin, end + 1)
        f = plt.figure() #
        ax = f.add_subplot(111) #
        nData = len(data) # the number of lines we will plot
        markers = list('+ox^psDv')
        s = '--'
    
        for i in range(nData): # add line-by-line
            m = markers[i % len(markers)]
            ax.plot(yearRange, data[i], label = dataTypeList[i], marker = m, linewidth = 2, linestyle = s)
    
        # text for labels
        ax.set_xlabel(self.xlabel)
        ax.set_ylabel('')
        ax.set_title(u'Gráfico de Linhas (Vários dados)') #especial
    
        # add grid, legend and title
        ax.legend(loc = 'best', prop = {'size':'small'})
        plt.grid(True)
        return f
